#!/usr/bin/env python3
# 重复文件收集工具 - 扫描指定目录下的所有文件，查找重复文件并生成JSON报告
# 使用方法:
# python dup_collect.py -folder "c:\123" -result "c:\abc"
# 参数说明:
#   -folder: 要检查的根目录，程序将递归扫描此目录下的所有文件
#   -result: 结果文件保存目录，将生成"重复文件列表+日期时间.json"格式的文件

import os
import hashlib
import json
import argparse
from datetime import datetime

def calculate_md5(file_path):
    """计算文件的MD5哈希值"""
    hash_md5 = hashlib.md5()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

def find_duplicate_files(root_folder):
    """查找指定目录下的所有重复文件"""
    hash_dict = {}
    processed_files = 0
    total_files = sum(len(files) for _, _, files in os.walk(root_folder))
    
    print(f"开始扫描目录: {root_folder}")
    print(f"发现 {total_files} 个文件需要处理")
    
    # 遍历目录树
    for dirpath, _, filenames in os.walk(root_folder):
        for filename in filenames:
            file_path = os.path.join(dirpath, filename)
            processed_files += 1
            
            # 每处理100个文件打印一次进度
            if processed_files % 100 == 0 or processed_files == total_files:
                progress = (processed_files / total_files) * 100
                print(f"进度: {processed_files}/{total_files} 文件 ({progress:.1f}%)")
            
            try:
                # 计算文件的MD5
                print(f"正在计算文件MD5: {file_path}")
                file_hash = calculate_md5(file_path)
                
                # 将文件路径添加到对应的哈希列表中
                if file_hash in hash_dict:
                    print(f"发现重复文件: {file_path} (MD5: {file_hash})")
                    hash_dict[file_hash].append(file_path)
                else:
                    hash_dict[file_hash] = [file_path]
            except (OSError, PermissionError) as e:
                print(f"无法处理文件 {file_path}: {e}")
    
    print(f"扫描完成，发现 {len(hash_dict)} 个不同的文件哈希值")
    return hash_dict

def main():
    # 设置命令行参数解析
    parser = argparse.ArgumentParser(description="查找并收集重复文件")
    parser.add_argument("-folder", required=True, help="要检查的根目录")
    parser.add_argument("-result", required=True, help="结果文件保存目录")
    args = parser.parse_args()

    # 确保结果目录存在
    os.makedirs(args.result, exist_ok=True)
    
    # 生成结果文件名
    current_time = datetime.now().strftime("%Y%m%d%H%M")
    result_filename = f"重复文件列表{current_time}.json"
    result_path = os.path.join(args.result, result_filename)
    
    # 查找重复文件
    duplicate_files = find_duplicate_files(args.folder)
    
    # 保存结果到JSON文件
    print(f"正在保存结果到: {result_path}")
    with open(result_path, 'w', encoding='utf-8') as f:
        json.dump(duplicate_files, f, ensure_ascii=False, indent=4)
    
    print(f"重复文件检测完成，结果已保存至: {result_path}")

if __name__ == "__main__":
    main()    